package cn.xyt.service;

import java.math.BigInteger;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.sql.Timestamp;
import java.util.Calendar;

import cn.tom.db.jdbc.simple.DBUtil;
import cn.tom.kit.IoBuffer;
import cn.xyt.dto.Message;
import cn.xyt.dto.VoltInfo;
import cn.xyt.util.ByteUtil;
import cn.xyt.util.JPushUtil;
import cn.xyt.util.MapUtil;
import cn.xyt.util.MessageThreadPool;

public class MessageServiceByZc extends MessageService{
	
	
	/**
	 * 鉴权登录
	 * @param body
	 * @return
	 */
	@Override
	public byte[] login(Message msg) {
		IoBuffer body = msg.getBodyBuf();
		short serial = body.readShort();
		int loginsize = body.readByte();
		byte [] loginid = new byte[loginsize];
		body.readBytes(loginid);
		int bsize =  body.readByte();
		byte [] blebyte = new byte [bsize];
		body.readBytes(blebyte);
		String _bleid = new String(blebyte ,Charset.forName("UTF-8")) ;
		int deviceid = msg.getHeader().getDeviceid();
		DBUtil.exec("update deviceauth set bleid=?,ctime=now() where id=? and bleid<>?", _bleid, deviceid,_bleid);
		DBUtil.exec("update life set bleid=? where did=? and bleid<>?", _bleid, deviceid,_bleid);
		DBUtil.exec("INSERT INTO deviceset(deviceid, bleid) VALUES(?, ?) ON CONFLICT (deviceid) DO UPDATE set deviceid =?",
				deviceid,_bleid, deviceid);
		IoBuffer resBody = getLittleBuf();
		int cnt = DBUtil.getInt("select count(*) from deviceauth where auth =? and id=?", new BigInteger(loginid).longValue(),deviceid);
		// 登录状态
		int loginState = cnt==1 ? 1:2;
		// 推送 上线状态
		if(cnt == 1) JPushUtil.pushLoginState(deviceid);
		
		resBody.writeByte(loginState);
		IoBuffer date = getLittleBuf(6);
		Calendar c = Calendar.getInstance();
		date.writeByte(c.get(Calendar.YEAR)-2000);
		date.writeByte(c.get(Calendar.MONTH));
		date.writeByte(c.get(Calendar.DAY_OF_MONTH));
		date.writeByte(c.get(Calendar.HOUR_OF_DAY));
		date.writeByte(c.get(Calendar.MINUTE));
		date.writeByte(c.get(Calendar.SECOND));
		resBody.writeBytes(date.array());
		return resBody.flip().readBytes(0, resBody.limit());
	}
	
	
	/**
	 * 设备基础信息上报
	 *  添加启动关闭 上报
	 * @param body
	 * @return
	 */
	@Override
	public byte[] diviceInfo(Message msg) {
		IoBuffer body = msg.getBodyBuf();
		String softVersion = new StringBuffer()
				.append((int)body.readByte()&0xff).append('.')
				.append((int)body.readByte()&0xff).append('.')
				.append((int)body.readByte()&0xff).append('.')
				.append(String.format("%03d", (int)body.readByte()&0xff)).toString();
		int deviceid = msg.getHeader().getDeviceid();
		String hardwareVersion = (body.readByte()&0xff)+"."+(body.readByte()&0xff);
		byte _gpsState = body.readByte();
		String gpsState = ByteUtil.byteToBit(_gpsState);
		int gsmState = body.readByte();
		float nvolt = (float)(0.1 * body.readByte());
		float wvolt = (float)(0.1 * body.readShort());
		
		byte _switch1 = body.readByte();
		// TODO  添加启动关闭 上报
//		if(((_switch1>>4)&0x01) == 1){  
//			JPushUtil.pushMove(deviceid, (_switch1>>2)&0x01);
//		}
		String switch1 = ByteUtil.byteToBit(_switch1);
		byte _switch2 = body.readByte();
		String switch2 = ByteUtil.byteToBit(_switch2);
		byte _switch3 = body.readByte();
		String switch3 = ByteUtil.byteToBit(_switch3);
		
		byte _gpsworkState = body.readByte();
		String gpsworkState = ByteUtil.byteToBit(_gpsworkState);
		
		short lac =  body.readShort(); //基站lac
		short rssi =   body.readShort(); //基站rssi
		
		if(msg.getHeader().getSerial()%2==0){  // 取消 数据插入
			return null;
		}
		DBUtil.exec("INSERT INTO deviceinfo (did, sversion, hversion, gpsstate, gsmstate, nvolt, wvolt, switch1, switch2, switch3, gpsworkstate, lac, rssi) " +
				"VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)", deviceid, softVersion, hardwareVersion,gpsState, gsmState,nvolt,wvolt,switch1,
														switch2,switch3,gpsworkState, lac,rssi);
		
		DBUtil.exec("update deviceone set sversion=?, hversion=?, gpsstate=?, gsmstate=?, nvolt=?, wvolt=?, switch1=?, switch2=?, switch3=?,"
				+ " gpsworkstate=?, lac=?, rssi=?, ctime =now() where did =?", softVersion, hardwareVersion,gpsState, gsmState,nvolt,wvolt,switch1, switch2,
					switch3,gpsworkState, lac,rssi,  deviceid);
		return null;
	}
	

	@Override
	public byte[] heart(Message msg) { 
		IoBuffer body = msg.getBodyBuf();
		int state = body.readByte();
		int deviceid = msg.getHeader().getDeviceid();
		if(state ==0){ // 0有效定位, 1无效定位
			int year = 2000 + body.readByte();
			int month = body.readByte();
			int day = body.readByte();
			int hour = body.readByte() + 8; //时间 +8
			int minute = body.readByte();
			int second = body.readByte();
			char ew = (char) body.readByte(); // ‘E’东经 ‘W’西经
			double lon = (double)body.readInt()/1000000;   
			char ns = (char) body.readByte(); // ‘N’北纬  ‘S’南纬
			double lat = (double)body.readInt()/1000000;   
			if(lon<72 || lat <17){
				return null;
			}
			double[] lat_lon = MapUtil.wgs2gcj(lat, lon); // 转高德地图
			
			int height = body.readShort();
			int speed = body.readShort();
			int orientation  = body.readShort(); //方位
			int mileage = body.readInt(); //里程
			
			Calendar c = Calendar.getInstance();
			c.set(year, month-1, day, hour, minute, second);
			
			DBUtil.exec("INSERT INTO gpslog (did, lat, lon, ew, ns, height, speed, orientation, mileage, ctime) " +
					"VALUES(?,?,?,?,?,?,?,?,?,?)", deviceid, lat_lon[0],lat_lon[1],ew,ns,height,speed,orientation,mileage,new Timestamp(c.getTimeInMillis()));
			DBUtil.exec("update gpsone set lat =?,lon=?,height=?,speed=?,orientation=?, mileage=?, ctime=? where did=?", 
					lat_lon[0],lat_lon[1],height,speed,orientation,mileage,new Timestamp(c.getTimeInMillis()), deviceid);
			
			//运动时推送GPS经纬度, 用来检查实时检查是否跑到区域外
			// TODO 天邮的 艾特出行 益约有这个功能, 其他没有
			//if(speed>100 || orientation>100)  JPushUtil.pushGps(deviceid, lat_lon[0],lat_lon[1]);
		}
		
		return null;
		
	}
	
	@Override
	public byte[] batchvoltInfo(Message msg) {
		IoBuffer body = msg.getBodyBuf();
		int deviceid = msg.getHeader().getDeviceid();
		int cnt =  body.readByte();
		while(body.remaining()>0){
			byte []b = new byte[21]; 
			body.readBytes(b);
			parseVoltInfo(deviceid, IoBuffer.wrap(b));
		}
		return null;
	}
	
	
	@Override
	public void parseVoltInfo(int deviceid, IoBuffer info){
		info.buf().order(ByteOrder.LITTLE_ENDIAN);
		info.readInt();
		
		int year = 2000 + info.readByte();
		int month = info.readByte();
		int day = info.readByte();
		int hour = info.readByte();
		int minute = info.readByte();
		int second = info.readByte();
		
		float volt = (float) (info.readShort()*0.1); //电压
		byte stat1 = info.readByte();
		String state1 = ByteUtil.byteToBit(stat1);
		float elec = (float) ((info.readByte()&0xff)*0.1); //电流
		byte stat2 = info.readByte();
		String state2 = ByteUtil.byteToBit(stat2);
		short pl = info.readShort();  // 当次运行最多频率
		int mlcnt = info.readInt();  // 当次脉冲数
		
		Calendar c = Calendar.getInstance();
		
		DBUtil.exec("INSERT INTO voltinfo(did, volt, elec, state1, state2, pl, mlcnt, ctime)" +
				" VALUES(?,?,?,?,?,?,?,?)", deviceid, volt, elec, state1, state2, pl, mlcnt, new Timestamp(c.getTimeInMillis()));
		DBUtil.exec("update  voltone set volt=?, elec=?, state1=?, state2=?, pl=?, mlcnt=?, ctime=? where did=?", 
				volt, elec, state1, state2, pl, mlcnt, new Timestamp(c.getTimeInMillis()), deviceid);
		
		final VoltInfo voltInfo = new VoltInfo(deviceid, volt, state1, elec, state2, pl, mlcnt, c);
		MessageThreadPool.executeMessageTask(new Runnable() {
			@Override
			public void run() {
				try{
					workout(voltInfo);
				}catch(Exception e){
					logger.info(e.getMessage(),e);
				}
			}
		});
	}
	
	
	/**
	 * 批量上报报警信息
	 * @param msg
	 * @return
	 */
	@Override
	public byte[] batchwarnInfo(Message msg) {
		IoBuffer body = msg.getBodyBuf();
		int cnt =  body.readByte();
		while(body.remaining()>0){
			byte [] info = new byte[11];
			body.readBytes(info);
			parseWarnInfo(msg.getHeader().getDeviceid(),  IoBuffer.wrap(info));
		}
		return null;
	}
	
	@Override
	public void parseWarnInfo(int deviceid, IoBuffer body){
		body.readInt();
		
		int year = 2000 + body.readByte();
		int month = body.readByte();
		int day = body.readByte();
		int hour = body.readByte();
		int minute = body.readByte();
		int second = body.readByte();
		
		byte s = body.readByte(); // 报警状态
		String state = ByteUtil.byteToBit(s);
		Calendar c = Calendar.getInstance();
		DBUtil.exec("insert into warninfo(did, state, ctime) values(?,?,?)", deviceid, state, new Timestamp(c.getTimeInMillis()));
		JPushUtil.pushWarn(state, deviceid);
	}

}
